// ScribbleView.cpp : implementation of the CScribbleView class
//

#include "stdafx.h"
#include "Scribble.h"
#include"Stroke.h"
#include "ScribbleDoc.h"
#include "ScribbleView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CScribbleView

IMPLEMENT_DYNCREATE(CScribbleView, CScrollView)

BEGIN_MESSAGE_MAP(CScribbleView, CScrollView)
	//{{AFX_MSG_MAP(CScribbleView)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CScribbleView construction/destruction

CScribbleView::CScribbleView()
{
	// TODO: add construction code here

}

CScribbleView::~CScribbleView()
{
}

BOOL CScribbleView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
    
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CScribbleView drawing

void CScribbleView::OnDraw(CDC* pDC)
{//this is a test of the CStroke::drawStrode() member!
    CScribbleDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
/*	CStroke stroke(12);
	stroke.m_pointArray.Add(CPoint(0,0));
	stroke.m_pointArray.Add(CPoint(100,100));
	stroke.m_pointArray.Add(CPoint(0,233));
	TRACE("The size of the array is %d \n",stroke.m_pointArray.GetSize());
	if(stroke.m_pointArray.GetSize()>3)
		return;

	 BOOL bResult=stroke.DrawStroke(pDC); 
*/	CRect  rectClip;
	CRect rectStroke;
	pDC->GetClipBox(&rectClip);

	CTypedPtrList<CObList,CStroke*> &strokeList=pDoc->m_strokeList;
	POSITION pos=strokeList.GetHeadPosition();
	while(pos!=NULL)
	{
		CStroke *pStroke=strokeList.GetNext(pos);
		pStroke->DrawStroke(pDC);
		//these
		rectStroke=pStroke->GetBoundingRect();
		if(!rectStroke.IntersectRect(&rectStroke,&rectClip))
			continue;
		pStroke->DrawStroke(pDC);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CScribbleView printing

BOOL CScribbleView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CScribbleView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CScribbleView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CScribbleView diagnostics

#ifdef _DEBUG
void CScribbleView::AssertValid() const
{
	CView::AssertValid();
}

void CScribbleView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CScribbleDoc* CScribbleView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CScribbleDoc)));
	return (CScribbleDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CScribbleView message handlers

void CScribbleView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&point);
	m_pStrokeCur=GetDocument()->NewStroke();
    m_pStrokeCur->m_pointArray.Add(point);
	SetCapture();
	m_ptPrev=point;
	CView::OnLButtonDown(nFlags, point);
}

void CScribbleView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(GetCapture()!=this)
		return;
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&point);

	CScribbleDoc*pDoc=GetDocument();
 	CPen *pOldPen=dc.SelectObject(pDoc->GetCurrentPen());
	dc.MoveTo(m_ptPrev);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	m_pStrokeCur->m_pointArray.Add(point);
	m_pStrokeCur->FinishStroke();
	pDoc->UpdateAllViews(this,0L,m_pStrokeCur);
	ReleaseCapture();
	return;
//	CView::OnLButtonUp(nFlags, point);
}

void CScribbleView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(GetCapture()!=this)
		return;
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&point);
	m_pStrokeCur->m_pointArray.Add(point);
	CPen *pOldPen=dc.SelectObject(GetDocument()->GetCurrentPen());
	dc.MoveTo(m_ptPrev);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	m_ptPrev=point;
	return;
	CView::OnMouseMove(nFlags, point);
}

void CScribbleView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(pHint!=NULL)
	{
		if(pHint->IsKindOf(RUNTIME_CLASS(CStroke)))
		{
			CStroke*pStroke=(CStroke*)pHint;

			CClientDC dc(this);
			OnPrepareDC(&dc);
 
 
			CRect rectInvalid=pStroke->GetBoundingRect();
			dc.LPtoDP(&rectInvalid);
			InvalidateRect(&rectInvalid);
			return;
		}
	}
	Invalidate(TRUE);
	return;
}

void CScribbleView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	SetScrollSizes(MM_TEXT,GetDocument()->GetDocSize());
}
